﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace AspDIY.Net.Common
{
    /// <summary>
    /// 验证类
    /// </summary>
    public class Validator
    {
        #region 字符串正则
        private const string Chinese = @"^[\u4E00-\u9FA5\uF900-\uFA2D]+$";
        private const string Color = "^#[a-fA-F0-9]{6}";
        private const string Date = @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29))$";
        private const string DateTime = @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$";
        private const string Email = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$";
        private const string Float = @"^(-?\d+)(\.\d+)?$";
        private const string ImageFormat = @"\.(?i:jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$";
        private const string Integer = @"^-?\d+$";
        private const string IP = @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$";
        private const string Letter = "^[A-Za-z]+$";
        private const string LowerLetter = "^[a-z]+$";
        private const string MinusFloat = @"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$";
        private const string MinusInteger = "^-[0-9]*[1-9][0-9]*$";
        private const string Mobile = "^0{0,1}13[0-9]{9}$";
        private const string NumbericOrLetterOrChinese = @"^[A-Za-z0-9\u4E00-\u9FA5\uF900-\uFA2D]+$";
        private const string Numeric = "^[0-9]+$";
        private const string NumericOrLetter = "^[A-Za-z0-9]+$";
        private const string NumericOrLetterOrUnderline = @"^\w+$";
        private const string PlusFloat = @"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$";
        private const string PlusInteger = "^[0-9]*[1-9][0-9]*$";
        private const string Telephone = @"(\d+-)?(\d{4}-?\d{7}|\d{3}-?\d{8}|^\d{7,8})(-\d+)?";
        private const string UnMinusFloat = @"^\d+(\.\d+)?$";
        private const string UnMinusInteger = @"\d+$";
        private const string UnPlusFloat = @"^((-\d+(\.\d+)?)|(0+(\.0+)?))$";
        private const string UnPlusInteger = @"^((-\d+)|(0+))$";
        private const string UpperLetter = "^[A-Z]+$";
        private const string Url = @"^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{1,10}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$";
        private const string Base64 = @"[A-Za-z0-9\+\/\=]";
        private const string SafeSql = @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']";


        #endregion

        #region 字符串验证

        /// <summary>
        /// 判断是否为base64字符串
        /// </summary>
        /// <param name="strValue">要判断字符串</param>
        /// <returns></returns>
        public static bool IsBase64String(string strValue)
        {
            //A-Z, a-z, 0-9, +, /, =
            return Regex.IsMatch(strValue, Base64);
        }
        /// <summary>
        /// 检测是否有Sql危险字符
        /// </summary>
        /// <param name="strValue">要判断字符串</param>
        /// <returns>判断结果</returns>
        public static bool IsSafeSqlString(string strValue)
        {
            return !Regex.IsMatch(strValue, SafeSql);
        }

        /// <summary>
        /// 验证非负整数（正整数 + 0）
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsUnMinusInt(string strValue)
        {
            return Regex.IsMatch(strValue, UnMinusInteger);
        }

        /// <summary>
        /// 验证正整数
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsPlusInt(string strValue)
        {
            return Regex.IsMatch(strValue, PlusInteger);
        }

        /// <summary>
        /// 验证非正整数（负整数 + 0） 
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsUnPlusInt(string strValue)
        {
            return Regex.IsMatch(strValue, UnPlusInteger);
        }

        /// <summary>
        /// 验证负整数
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsMinusInt(string strValue)
        {
            return Regex.IsMatch(strValue, MinusInteger);
        }

        /// <summary>
        /// 验证整数
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsInt(string strValue)
        {
            return Regex.IsMatch(strValue, Integer);
        }

        /// <summary>
        /// 验证非负浮点数（正浮点数 + 0）
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsUnMinusFloat(string strValue)
        {
            return Regex.IsMatch(strValue, UnMinusFloat);
        }

        /// <summary>
        /// 验证正浮点数
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsPlusFloat(string strValue)
        {
            return Regex.IsMatch(strValue, PlusFloat);
        }

        /// <summary>
        /// 验证非正浮点数（负浮点数 + 0）
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsUnPlusFloat(string strValue)
        {
            return Regex.IsMatch(strValue, UnPlusFloat);
        }

        /// <summary>
        /// 验证负浮点数
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsMinusFloat(string strValue)
        {
            return Regex.IsMatch(strValue, MinusFloat);
        }

        /// <summary>
        /// 验证浮点数
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsFloat(string strValue)
        {
            return Regex.IsMatch(strValue, Float);
        }

        /// <summary>
        /// 验证由26个英文字母组成的字符串
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsLetter(string strValue)
        {
            return Regex.IsMatch(strValue, Letter);
        }

        /// <summary>
        /// 验证由中文组成的字符串
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsChinese(string strValue)
        {
            return Regex.IsMatch(strValue, Chinese);
        }

        /// <summary>
        /// 验证由26个英文字母的大写组成的字符串
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsUpperLetter(string strValue)
        {
            return Regex.IsMatch(strValue, UpperLetter);
        }

        /// <summary>
        /// 验证由26个英文字母的小写组成的字符串
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsLowerLetter(string strValue)
        {
            return Regex.IsMatch(strValue, LowerLetter);
        }

        /// <summary>
        /// 验证由数字和26个英文字母组成的字符串
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsNumericOrLetter(string strValue)
        {
            return Regex.IsMatch(strValue, NumericOrLetter);
        }

        /// <summary>
        /// 验证由数字组成的字符串
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsNumeric(string strValue)
        {
            return Regex.IsMatch(strValue, Numeric);
        }
        /// <summary>
        /// 验证由数字和26个英文字母或中文组成的字符串
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsNumericOrLetterOrChinese(string strValue)
        {
            return Regex.IsMatch(strValue, NumbericOrLetterOrChinese);
        }

        /// <summary>
        /// 验证由数字、26个英文字母或者下划线组成的字符串
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsNumericOrLetterOrUnderline(string strValue)
        {
            return Regex.IsMatch(strValue, NumericOrLetterOrUnderline);
        }
        /// <summary>
        /// 验证email地址
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsEmail(string strValue)
        {
            return Regex.IsMatch(strValue, Email);
        }

        /// <summary>
        /// 验证URL
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsUrl(string strValue)
        {
            return Regex.IsMatch(strValue, Url);
        }

        /// <summary>
        /// 验证电话号码
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsTelephone(string strValue)
        {
            return Regex.IsMatch(strValue, Telephone);
        }

        /// <summary>
        /// 验证手机号码
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsMobile(string strValue)
        {
            return Regex.IsMatch(strValue, Mobile);
        }

        /// <summary>
        /// 通过文件扩展名验证图像格式
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsImageFormat(string strValue)
        {
            return Regex.IsMatch(strValue, ImageFormat);
        }

        /// <summary>
        /// 验证IP
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsIP(string strValue)
        {
            return Regex.IsMatch(strValue, IP);
        }

        /// <summary>
        /// 验证日期（YYYY-MM-DD）
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsDate(string strValue)
        {
            return Regex.IsMatch(strValue, Date);
        }

        /// <summary>
        /// 验证日期和时间（YYYY-MM-DD HH:MM:SS）
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsDateTime(string strValue)
        {
            return Regex.IsMatch(strValue, DateTime);
        }

        /// <summary>
        /// 验证颜色（#ff0000）
        /// </summary>
        /// <param name="strValue">要验证的字符串</param>
        /// <returns>验证通过返回true</returns>
        public static bool IsColor(string strValue)
        {
            return Regex.IsMatch(strValue, Color);
        }
        #endregion
    }
}
